#include <iostream>  
#include <vector>  
#include <string>  
#include <cstring>  
  
// 牛牛和他的朋友们约定了一套接头密匙系统，用于确认彼此身份
// 密匙由一组数字序列表示，两个密匙被认为是一致的，如果满足以下条件：
// 密匙 b 的长度不超过密匙 a 的长度。
// 对于任意 0 <= i < length(b)，有b[i+1] - b[i] == a[i+1] - a[i]
// 现在给定了m个密匙 b 的数组，以及n个密匙 a 的数组
// 请你返回一个长度为 m 的结果数组 ans，表示每个密匙b都有多少一致的密匙
// 数组 a 和数组 b 中的元素个数均不超过 10^5
// 1 <= m, n <= 1000
// 测试链接 : https://www.nowcoder.com/practice/c552d3b4dfda49ccb883a6371d9a6932
using namespace std;  
  
const int MAXN = 2000001;  
  
struct TrieNode {  
    TrieNode* children[12];  
    int passCount;  
    TrieNode() : passCount(0) {  
        memset(children, 0, sizeof(children));  
    }  
};  
  
TrieNode* root = new TrieNode();  
int nodeCount = 1;  
  
int path(char cha) {  
    if (cha == '#') {  
        return 10;  
    } else if (cha == '-') {  
        return 11;  
    } else {  
        return cha - '0';  
    }  
}  
  
void insert(const string& word) {  
    TrieNode* cur = root;  
    cur->passCount++;  
    for (char ch : word) {  
        int idx = path(ch);  
        if (cur->children[idx] == nullptr) {  
            cur->children[idx] = new TrieNode();  
            nodeCount++;  
        }  
        cur = cur->children[idx];  
        cur->passCount++;  
    }  
}  
  
int count(const string& pre) {  
    TrieNode* cur = root;  
    for (char ch : pre) {  
        int idx = path(ch);  
        if (cur->children[idx] == nullptr) {  
            return 0;  
        }  
        cur = cur->children[idx];  
    }  
    return cur->passCount;  
}  
  
void clearTrie() {  
    queue<TrieNode*> q;  
    q.push(root);  
    while (!q.empty()) {  
        TrieNode* cur = q.front();  
        q.pop();  
        for (TrieNode* child : cur->children) {  
            if (child != nullptr) {  
                q.push(child);  
            }  
        }  
        delete cur;  
    }  
    root = new TrieNode();  
    nodeCount = 1;  
}  
  
vector<int> countConsistentKeys(vector<vector<int>>& b, vector<vector<int>>& a) {  
    build();  
    for (const auto& nums : a) {  
        string builder;  
        for (size_t i = 1; i < nums.size(); i++) {  
            builder += to_string(nums[i] - nums[i - 1]) + "#";  
        }  
        insert(builder);  
    }  
    vector<int> ans(b.size());  
    for (size_t i = 0; i < b.size(); i++) {  
        string builder;  
        const auto& nums = b[i];  
        for (size_t j = 1; j < nums.size(); j++) {  
            builder += to_string(nums[j] - nums[j - 1]) + "#";  
        }  
        ans[i] = count(builder);  
    }  
    clearTrie();  
    return ans;  
}  
  
// Dummy main function to test the implementation  
int main() {  
    vector<vector<int>> a = {{1, 2, 3}, {4, 5, 6, 7}};  
    vector<vector<int>> b = {{2, 3}, {4, 6}};  
    vector<int> result = countConsistentKeys(b, a);  
    for (int count : result) {  
        cout << count << " ";  
    }  
    cout << endl;  
    return 0;  
}